
module Vec2i =
struct
  type t = int * int;;
  let add (x0, y0) (x1, y1) = (x0+x1, y0+y1);;
  let sub (x0, y0) (x1, y1) = (x0-x1, y0-y1);;
  let scale (x0, y0) s = (s*x0, s*y0);;
  let dot (x0, y0) (x1, y1) = (x0*x1 + y0*y1);;
  let write_binary ch (x0, y0) =
    output_binary_int ch x0;
    output_binary_int ch y0;;
  let read_binary ch =
    (input_binary_int ch, input_binary_int ch)
  let to_string (x0, y0) =
    "(" ^ (string_of_int x0) ^ ", " ^ (string_of_int y0) ^ ")"
end;;

module Rect2i =
struct
  type t = Vec2i.t * Vec2i.t   (* (xmin,ymin), (xmax, ymax) *)
  let is_inside (x, y) (((xmin, ymin), (xmax, ymax)):t) =
    x >= xmin && x <= xmax && y >= ymin && y <= ymax;;
  let do_intersect (((xmin0, ymin0), (xmax0, ymax0)):t) 
      (((xmin1, ymin1), (xmax1, ymax1)):t) =
    xmin0 <= xmax1 && xmax0 >= xmin1 &&
      ymin0 <= ymax1 && ymax0 >= ymin1;;
  let write_binary ch (min, max) =
    Vec2i.write_binary ch min;
    Vec2i.write_binary ch max;;
  let read_binary ch =
    (Vec2i.read_binary ch, Vec2i.read_binary ch);;
  let to_string (min, max) =
    "(" ^ (Vec2i.to_string min) ^ ", " ^ (Vec2i.to_string max) ^ ")"
end

module Vec3f =
struct
  type t = float * float * float
  let add (x0, y0, z0) (x1, y1, z1) = (x0+.x1, y0+.y1, z0+.z1)
  let sub (x0, y0, z0) (x1, y1, z1) = (x0-.x1, y0-.y1, z0-.z1)
  let scale (x0, y0, z0) s = (s*.x0, s*.y0, s*.z0)
  let dot (x0, y0, z0) (x1, y1, z1) = (x0*.x1 +. y0*.y1 +. z0*.z1)
end;;
